// src/scenarios/manufacturing.rs

//! 制造业设备场景
//! 支持生产制造设备的语义转换和OPC UA模型构建

use crate::scenarios::*;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// 制造业设备场景
pub struct ManufacturingEquipmentScenario {
    config: ScenarioConfig,
}

/// 制造业设备类型枚举
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ManufacturingEquipmentType {
    /// CNC机床
    CNCMachine,
    /// 工业机器人
    IndustrialRobot,
    /// 传送带
    ConveyorBelt,
    /// 包装机
    PackagingMachine,
    /// 质量检测设备
    QualityInspectionEquipment,
    /// 仓储设备
    StorageEquipment,
    /// 生产线
    ProductionLine,
    /// 其他设备
    Other(String),
}

/// 设备状态
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum EquipmentStatus {
    /// 运行中
    Running,
    /// 停机
    Stopped,
    /// 故障
    Fault,
    /// 维护中
    Maintenance,
    /// 待机
    Idle,
    /// 离线
    Offline,
}

/// 生产指标
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProductionMetrics {
    /// 设备综合效率(OEE)
    pub oee: f64,
    /// 可用性
    pub availability: f64,
    /// 性能效率
    pub performance_efficiency: f64,
    /// 质量率
    pub quality_rate: f64,
    /// 生产数量
    pub production_count: u64,
    /// 良品数量
    pub good_count: u64,
    /// 次品数量
    pub defective_count: u64,
    /// 循环时间（秒）
    pub cycle_time_seconds: f64,
    /// 停机时间（秒）
    pub downtime_seconds: f64,
}

/// 设备参数
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EquipmentParameters {
    /// 温度（摄氏度）
    pub temperature: Option<f64>,
    /// 压力（帕斯卡）
    pub pressure: Option<f64>,
    /// 速度（转/分钟）
    pub speed_rpm: Option<f64>,
    /// 功率（瓦特）
    pub power_watts: Option<f64>,
    /// 电流（安培）
    pub current_amperes: Option<f64>,
    /// 电压（伏特）
    pub voltage_volts: Option<f64>,
    /// 振动（毫米/秒）
    pub vibration_mm_per_sec: Option<f64>,
    /// 噪音（分贝）
    pub noise_decibels: Option<f64>,
    /// 湿度（百分比）
    pub humidity_percent: Option<f64>,
}

impl ManufacturingEquipmentScenario {
    /// 创建新的制造业设备场景
    pub fn new() -> Self {
        Self {
            config: ScenarioConfig {
                name: Some("制造业设备语义转换场景".to_string()),
                description: Some("支持制造业设备数据的语义转换和OPC UA模型构建，包括CNC机床、工业机器人、传送带等设备类型".to_string()),
                custom_rules: None,
                extensions: HashMap::new(),
            },
        }
    }

    /// 使用配置创建场景
    pub fn new_with_config(config: ScenarioConfig) -> Self {
        Self { config }
    }

    /// 创建CNC机床转换规则
    fn create_cnc_machine_rules(&self) -> ScenarioTransformationRules {
        let mut mappings = HashMap::new();

        // 数据源类型映射
        mappings.insert("spindle_speed".to_string(), "RotationalSpeed".to_string());
        mappings.insert("feed_rate".to_string(), "LinearVelocity".to_string());
        mappings.insert("tool_number".to_string(), "ToolIdentifier".to_string());
        mappings.insert("program_number".to_string(), "ProgramIdentifier".to_string());
        mappings.insert("axis_position".to_string(), "Position".to_string());
        mappings.insert("coolant_status".to_string(), "CoolantState".to_string());

        // 单位转换
        let mut unit_conversions = HashMap::new();
        unit_conversions.insert("rpm_to_rad_per_sec".to_string(), UnitConversion {
            from_unit: "rpm".to_string(),
            to_unit: "rad/s".to_string(),
            conversion_factor: 2.0 * std::f64::consts::PI / 60.0,
            conversion_formula: Some("rpm * 2π / 60".to_string()),
        });

        unit_conversions.insert("mm_to_m".to_string(), UnitConversion {
            from_unit: "mm".to_string(),
            to_unit: "m".to_string(),
            conversion_factor: 0.001,
            conversion_formula: Some("mm / 1000".to_string()),
        });

        // 语义标签映射
        let mut semantic_mappings = HashMap::new();
        semantic_mappings.insert("cnc_machine".to_string(), vec![
            "ManufacturingEquipment".to_string(),
            "MetalWorking".to_string(),
            "CNC".to_string(),
            "PrecisionMachining".to_string(),
        ]);

        ScenarioTransformationRules {
            rule_name: "CNC_Machine_Transformation".to_string(),
            data_source_mappings: mappings,
            unit_conversions,
            data_type_mappings: HashMap::new(),
            semantic_mappings,
            constraints: vec![
                ScenarioConstraint {
                    name: "valid_spindle_speed".to_string(),
                    constraint_type: "range".to_string(),
                    field: "spindle_speed".to_string(),
                    value: serde_json::json!({"min": 0, "max": 24000}),
                    description: Some("主轴转速必须在有效范围内".to_string()),
                },
                ScenarioConstraint {
                    name: "valid_feed_rate".to_string(),
                    constraint_type: "range".to_string(),
                    field: "feed_rate".to_string(),
                    value: serde_json::json!({"min": 0, "max": 10000}),
                    description: Some("进给速度必须在有效范围内".to_string()),
                },
            ],
        }
    }

    /// 创建工业机器人转换规则
    fn create_robotics_rules(&self) -> ScenarioTransformationRules {
        let mut mappings = HashMap::new();

        // 数据源类型映射
        mappings.insert("joint_angle".to_string(), "JointPosition".to_string());
        mappings.insert("tcp_position".to_string(), "CartesianPosition".to_string());
        mappings.insert("tcp_orientation".to_string(), "Orientation".to_string());
        mappings.insert("payload_weight".to_string(), "Load".to_string());
        mappings.insert("program_name".to_string(), "ProgramIdentifier".to_string());
        mappings.insert("operation_mode".to_string(), "OperatingMode".to_string());

        // 单位转换
        let mut unit_conversions = HashMap::new();
        unit_conversions.insert("degrees_to_radians".to_string(), UnitConversion {
            from_unit: "deg".to_string(),
            to_unit: "rad".to_string(),
            conversion_factor: std::f64::consts::PI / 180.0,
            conversion_formula: Some("deg * π / 180".to_string()),
        });

        unit_conversions.insert("kg_to_n".to_string(), UnitConversion {
            from_unit: "kg".to_string(),
            to_unit: "N".to_string(),
            conversion_factor: 9.80665,
            conversion_formula: Some("kg * 9.80665".to_string()),
        });

        // 语义标签映射
        let mut semantic_mappings = HashMap::new();
        semantic_mappings.insert("industrial_robot".to_string(), vec![
            "ManufacturingEquipment".to_string(),
            "Robotics".to_string(),
            "Automation".to_string(),
            "ArticulatedArm".to_string(),
        ]);

        ScenarioTransformationRules {
            rule_name: "Industrial_Robotics_Transformation".to_string(),
            data_source_mappings: mappings,
            unit_conversions,
            data_type_mappings: HashMap::new(),
            semantic_mappings,
            constraints: vec![
                ScenarioConstraint {
                    name: "valid_joint_range".to_string(),
                    constraint_type: "range".to_string(),
                    field: "joint_angle".to_string(),
                    value: serde_json::json!({"min": -180, "max": 180}),
                    description: Some("关节角度必须在有效范围内".to_string()),
                },
                ScenarioConstraint {
                    name: "valid_payload".to_string(),
                    constraint_type: "range".to_string(),
                    field: "payload_weight".to_string(),
                    value: serde_json::json!({"min": 0, "max": 500}),
                    description: Some("负载重量必须在有效范围内".to_string()),
                },
            ],
        }
    }
}

impl Scenario for ManufacturingEquipmentScenario {
    fn name(&self) -> &'static str {
        "Manufacturing Equipment Semantic Conversion"
    }

    fn description(&self) -> &'static str {
        "制造业设备语义转换场景，支持CNC机床、工业机器人、传送带等设备的语义转换和OPC UA模型构建"
    }

    fn industry(&self) -> &'static str {
        "Manufacturing"
    }

    fn get_transformation_rules(&self) -> ScenarioTransformationRules {
        // 返回通用的制造业转换规则
        let mut mappings = HashMap::new();

        // 通用设备字段映射
        mappings.insert("equipment_id".to_string(), "DeviceIdentifier".to_string());
        mappings.insert("equipment_name".to_string(), "DeviceName".to_string());
        mappings.insert("equipment_type".to_string(), "DeviceType".to_string());
        mappings.insert("status".to_string(), "DeviceState".to_string());
        mappings.insert("production_count".to_string(), "ProductionCounter".to_string());
        mappings.insert("cycle_time".to_string(), "CycleTime".to_string());
        mappings.insert("oee".to_string(), "OverallEquipmentEffectiveness".to_string());

        // 通用单位转换
        let mut unit_conversions = HashMap::new();
        unit_conversions.insert("temperature_celsius_to_kelvin".to_string(), UnitConversion {
            from_unit: "°C".to_string(),
            to_unit: "K".to_string(),
            conversion_factor: 273.15,
            conversion_formula: Some("°C + 273.15".to_string()),
        });

        // 通用语义映射
        let mut semantic_mappings = HashMap::new();
        semantic_mappings.insert("manufacturing_equipment".to_string(), vec![
            "IndustrialEquipment".to_string(),
            "ProductionAsset".to_string(),
            "Manufacturing".to_string(),
        ]);

        ScenarioTransformationRules {
            rule_name: "Manufacturing_Equipment_General".to_string(),
            data_source_mappings: mappings,
            unit_conversions,
            data_type_mappings: HashMap::new(),
            semantic_mappings,
            constraints: vec![
                ScenarioConstraint {
                    name: "valid_equipment_status".to_string(),
                    constraint_type: "enum".to_string(),
                    field: "status".to_string(),
                    value: serde_json::json!(["Running", "Stopped", "Fault", "Maintenance", "Idle", "Offline"]),
                    description: Some("设备状态必须是有效值".to_string()),
                },
                ScenarioConstraint {
                    name: "valid_oee_range".to_string(),
                    constraint_type: "range".to_string(),
                    field: "oee".to_string(),
                    value: serde_json::json!({"min": 0.0, "max": 1.0}),
                    description: Some("OEE值必须在0-1之间".to_string()),
                },
            ],
        }
    }

    fn get_opcua_model_template(&self) -> ScenarioModelTemplate {
        ScenarioModelTemplate {
            template_name: "ManufacturingEquipmentModel".to_string(),
            namespaces: vec![
                "http://opcfoundation.org/UA/".to_string(),
                "http://iso.org/15745-1/2003/ID".to_string(),
                "http://industryagent.com/manufacturing/".to_string(),
            ],
            object_types: vec![
                ObjectTypeTemplate {
                    type_name: "ManufacturingEquipmentType".to_string(),
                    description: Some("制造业设备基础类型".to_string()),
                    parent_type: Some("BaseObjectType".to_string()),
                    properties: vec![
                        PropertyTemplate {
                            name: "EquipmentId".to_string(),
                            data_type: "String".to_string(),
                            description: Some("设备唯一标识符".to_string()),
                            unit: None,
                            required: true,
                            default_value: None,
                        },
                        PropertyTemplate {
                            name: "EquipmentName".to_string(),
                            data_type: "String".to_string(),
                            description: Some("设备名称".to_string()),
                            unit: None,
                            required: true,
                            default_value: None,
                        },
                        PropertyTemplate {
                            name: "EquipmentStatus".to_string(),
                            data_type: "EquipmentStatusEnum".to_string(),
                            description: Some("设备运行状态".to_string()),
                            unit: None,
                            required: true,
                            default_value: Some(serde_json::json!("Stopped")),
                        },
                        PropertyTemplate {
                            name: "ProductionCount".to_string(),
                            data_type: "UInt64".to_string(),
                            description: Some("生产计数".to_string()),
                            unit: None,
                            required: false,
                            default_value: Some(serde_json::json!(0)),
                        },
                        PropertyTemplate {
                            name: "CycleTime".to_string(),
                            data_type: "Duration".to_string(),
                            description: Some("循环时间".to_string()),
                            unit: Some("s".to_string()),
                            required: false,
                            default_value: None,
                        },
                        PropertyTemplate {
                            name: "OEE".to_string(),
                            data_type: "Double".to_string(),
                            description: Some("设备综合效率".to_string()),
                            unit: Some("%".to_string()),
                            required: false,
                            default_value: Some(serde_json::json!(0.0)),
                        },
                    ],
                    methods: vec![
                        MethodTemplate {
                            name: "StartEquipment".to_string(),
                            description: Some("启动设备".to_string()),
                            input_arguments: vec![],
                            output_arguments: vec![
                                ArgumentTemplate {
                                    name: "Success".to_string(),
                                    data_type: "Boolean".to_string(),
                                    description: Some("操作是否成功".to_string()),
                                    unit: None,
                                },
                            ],
                        },
                        MethodTemplate {
                            name: "StopEquipment".to_string(),
                            description: Some("停止设备".to_string()),
                            input_arguments: vec![],
                            output_arguments: vec![
                                ArgumentTemplate {
                                    name: "Success".to_string(),
                                    data_type: "Boolean".to_string(),
                                    description: Some("操作是否成功".to_string()),
                                    unit: None,
                                },
                            ],
                        },
                        MethodTemplate {
                            name: "ResetEquipment".to_string(),
                            description: Some("重置设备".to_string()),
                            input_arguments: vec![],
                            output_arguments: vec![
                                ArgumentTemplate {
                                    name: "Success".to_string(),
                                    data_type: "Boolean".to_string(),
                                    description: Some("操作是否成功".to_string()),
                                    unit: None,
                                },
                            ],
                        },
                    ],
                },
            ],
            variable_types: vec![
                VariableTypeTemplate {
                    type_name: "TemperatureSensorType".to_string(),
                    data_type: "Double".to_string(),
                    description: Some("温度传感器类型".to_string()),
                    unit: Some("°C".to_string()),
                    min_value: Some(-50.0),
                    max_value: Some(200.0),
                },
                VariableTypeTemplate {
                    type_name: "PressureSensorType".to_string(),
                    data_type: "Double".to_string(),
                    description: Some("压力传感器类型".to_string()),
                    unit: Some("Pa".to_string()),
                    min_value: Some(0.0),
                    max_value: Some(1000000.0),
                },
            ],
            reference_types: vec![
                ReferenceTypeTemplate {
                    type_name: "ControlsEquipment".to_string(),
                    description: Some("控制设备关系".to_string()),
                    parent_type: Some("Organizes".to_string()),
                    symmetric: false,
                },
                ReferenceTypeTemplate {
                    type_name: "MaintainsEquipment".to_string(),
                    description: Some("维护设备关系".to_string()),
                    parent_type: Some("Organizes".to_string()),
                    symmetric: false,
                },
            ],
        }
    }

    fn get_sample_data(&self) -> Vec<ScenarioSampleData> {
        vec![
            ScenarioSampleData {
                data_id: "cnc_machine_001".to_string(),
                data_source_type: "HuaweiCloudIoT".to_string(),
                raw_data: serde_json::json!({
                    "device_id": "CNC-001",
                    "device_name": "五轴加工中心-001",
                    "device_type": "CNC_Machine",
                    "status": "Running",
                    "spindle_speed": 12000,
                    "feed_rate": 500,
                    "tool_number": 5,
                    "program_number": "P1001",
                    "axis_position": {
                        "x": 150.5,
                        "y": 75.2,
                        "z": 25.8,
                        "a": 30.0,
                        "b": 15.0
                    },
                    "coolant_status": "ON",
                    "temperature": 45.2,
                    "production_count": 1250,
                    "cycle_time": 180.5,
                    "oee": 0.85,
                    "timestamp": "2024-01-15T10:30:00Z"
                }),
                expected_opcua: serde_json::json!({
                    "nodeId": "ns=2;i=1001",
                    "nodeClass": "Object",
                    "browseName": "CNC-001",
                    "typeDefinition": "ns=2;i=1000",
                    "components": [
                        {
                            "nodeId": "ns=2;i=1010",
                            "browseName": "SpindleSpeed",
                            "value": 1256.637, // converted to rad/s
                            "dataType": "Double"
                        },
                        {
                            "nodeId": "ns=2;i=1011",
                            "browseName": "FeedRate",
                            "value": 0.00833, // converted to m/s
                            "dataType": "Double"
                        },
                        {
                            "nodeId": "ns=2;i=1012",
                            "browseName": "EquipmentStatus",
                            "value": 2, // Running enum value
                            "dataType": "Int32"
                        },
                        {
                            "nodeId": "ns=2;i=1013",
                            "browseName": "OEE",
                            "value": 0.85,
                            "dataType": "Double"
                        }
                    ]
                }),
                description: Some("CNC五轴加工中心运行数据示例".to_string()),
                category: Some("MetalWorking".to_string()),
            },
            ScenarioSampleData {
                data_id: "industrial_robot_001".to_string(),
                data_source_type: "HuaweiCloudIoT".to_string(),
                raw_data: serde_json::json!({
                    "device_id": "ROBOT-001",
                    "device_name": "六轴工业机器人-001",
                    "device_type": "Industrial_Robot",
                    "status": "Running",
                    "joint_angles": [0.0, 45.0, -90.0, 0.0, 90.0, 0.0],
                    "tcp_position": {
                        "x": 500.0,
                        "y": 300.0,
                        "z": 800.0
                    },
                    "tcp_orientation": {
                        "roll": 0.0,
                        "pitch": 90.0,
                        "yaw": 0.0
                    },
                    "payload_weight": 15.5,
                    "program_name": "WELD_PROG_001",
                    "operation_mode": "AUTO",
                    "production_count": 850,
                    "timestamp": "2024-01-15T10:31:00Z"
                }),
                expected_opcua: serde_json::json!({
                    "nodeId": "ns=2;i=2001",
                    "nodeClass": "Object",
                    "browseName": "ROBOT-001",
                    "typeDefinition": "ns=2;i=2000",
                    "components": [
                        {
                            "nodeId": "ns=2;i=2010",
                            "browseName": "Joint1Position",
                            "value": 0.0, // converted to radians
                            "dataType": "Double"
                        },
                        {
                            "nodeId": "ns=2;i=2011",
                            "browseName": "Joint2Position",
                            "value": 0.785, // converted to radians
                            "dataType": "Double"
                        },
                        {
                            "nodeId": "ns=2;i=2020",
                            "browseName": "TCPPositionX",
                            "value": 0.5, // converted to meters
                            "dataType": "Double"
                        },
                        {
                            "nodeId": "ns=2;i=2021",
                            "browseName": "TCPPositionY",
                            "value": 0.3, // converted to meters
                            "dataType": "Double"
                        },
                        {
                            "nodeId": "ns=2;i=2030",
                            "browseName": "PayloadWeight",
                            "value": 152.0, // converted to Newtons
                            "dataType": "Double"
                        }
                    ]
                }),
                description: Some("六轴工业机器人运行数据示例".to_string()),
                category: Some("Robotics".to_string()),
            },
            ScenarioSampleData {
                data_id: "conveyor_belt_001".to_string(),
                data_source_type: "HuaweiCloudIoT".to_string(),
                raw_data: serde_json::json!({
                    "device_id": "CONVEYOR-001",
                    "device_name": "传送带-001",
                    "device_type": "ConveyorBelt",
                    "status": "Running",
                    "belt_speed": 2.5,
                    "motor_rpm": 1450,
                    "load_percentage": 75.0,
                    "temperature": 38.5,
                    "vibration": 2.1,
                    "items_count": 1250,
                    "stopped_items_count": 12,
                    "timestamp": "2024-01-15T10:32:00Z"
                }),
                expected_opcua: serde_json::json!({
                    "nodeId": "ns=2;i=3001",
                    "nodeClass": "Object",
                    "browseName": "CONVEYOR-001",
                    "typeDefinition": "ns=2;i=3000",
                    "components": [
                        {
                            "nodeId": "ns=2;i=3010",
                            "browseName": "BeltSpeed",
                            "value": 2.5,
                            "dataType": "Double",
                            "unit": "m/s"
                        },
                        {
                            "nodeId": "ns=2;i=3011",
                            "browseName": "LoadPercentage",
                            "value": 75.0,
                            "dataType": "Double",
                            "unit": "%"
                        },
                        {
                            "nodeId": "ns=2;i=3012",
                            "browseName": "ItemsCount",
                            "value": 1250,
                            "dataType": "UInt64"
                        }
                    ]
                }),
                description: Some("传送带运行数据示例".to_string()),
                category: Some("MaterialHandling".to_string()),
            },
        ]
    }

    fn get_semantic_mappings(&self) -> HashMap<String, String> {
        let mut mappings = HashMap::new();

        // 设备类型映射
        mappings.insert("CNC_Machine".to_string(), "MachineTool".to_string());
        mappings.insert("Industrial_Robot".to_string(), "Robot".to_string());
        mappings.insert("ConveyorBelt".to_string(), "MaterialHandlingSystem".to_string());
        mappings.insert("PackagingMachine".to_string(), "PackagingSystem".to_string());
        mappings.insert("QualityInspectionEquipment".to_string(), "QualityControlSystem".to_string());

        // 状态映射
        mappings.insert("Running".to_string(), "Operational".to_string());
        mappings.insert("Stopped".to_string(), "Halted".to_string());
        mappings.insert("Fault".to_string(), "Error".to_string());
        mappings.insert("Maintenance".to_string(), "UnderMaintenance".to_string());
        mappings.insert("Idle".to_string(), "Standby".to_string());

        // 参数映射
        mappings.insert("spindle_speed".to_string(), "RotationalSpeed".to_string());
        mappings.insert("feed_rate".to_string(), "FeedVelocity".to_string());
        mappings.insert("cycle_time".to_string(), "ProcessingTime".to_string());
        mappings.insert("production_count".to_string(), "ProductionQuantity".to_string());

        mappings
    }
}